Service Registration

What is service registration?#

Service registration is the process of a microservice registering its connection details in a service registry so that other microservices can discover it and connect to it.

A microservice registering its connection details in a service registry
A microservice registering its connection details in a service registry

A few important things to note about this in Kubernetes:

  1. Kubernetes uses an internal DNS service as its service registry.
  2. Services, not individual Pods, register with DNS.
  3. The name, IP address, and network port of every Service is registered

For this to work, Kubernetes provides a well known internal DNS service that we usually call the “cluster DNS”. The term well known means that it operates at an address known to every Pod and container in the cluster. It’s implemented in the kube-system Namespace as a set of Pods managed by a Deployment called coredns. These Pods are fronted by a Service called kube-dns. Behind the scenes, it’s based on a DNS technology, called CoreDNS, and runs as a Kubernetes-native application.

The previous sentence contains a lot of detail, so the following commands show how its implemented. You can run these commands on your own Kubernetes clusters.

Registration with cluster DNS#

Every Kubernetes Service is automatically registered with the cluster DNS when it’s created. The registration process looks like this (exact flow might slightly differ):

  1. You POST a new Service manifest to the API server.
  2. The request is authenticated, authorized, and subjected to admission policies.
  3. The Service is allocated a virtual IP address, called a ClusterIP.
  4. An Endpoints object (or Endpoint slices) is created to hold a list of Pods the Service will load balance traffic to.
  5. The Pod network is configured to handle traffic sent to the ClusterIP (more on this later).
  6. The Service’s name and IP are registered with the cluster DNS.

Step 6 is the secret sauce in the service registration process.

We mentioned earlier that the cluster DNS is a Kubernetes-native application. This means it knows it’s running on Kubernetes and implements a controller that watches the API server for new Service objects. Any time it observes a new Service object, it creates the DNS records that allow the Service name to be resolved to its ClusterIP. This means that applications and Services do not need to perform service registration – the cluster DNS is constantly looking for new Services and automatically registers their details.

It’s important to understand that the name registered for the Service is the value stored in its metadata.name property. The ClusterIP is dynamically assigned by Kubernetes.

At this point, the front-end configuration of the Service is registered (name, IP, port), and the Service can be discovered by applications running in other Pods.

The Service back end#

Now that the front end of the Service is registered, the back end needs building. This involves creating and maintaining a list of Pod IPs that the Service will load-balance traffic to.

As explained in the previous chapter, every Service has a label selector that determines which Pods the Service will load balance traffic to. See below:

Label selector determines which Pods the Service will load balance traffic to
Label selector determines which Pods the Service will load balance traffic to

Kubernetes automatically creates an Endpoints object (or Endpoint slices) for every Service. These hold the list of Pods that match the label selector and will receive traffic from the Service. They’re also critical to how traffic is routed from the Service’s ClusterIP to Pod IPs (more on this soon).

The following command shows an Endpoints object for a Service called ent. It has the IP address and port of two Pods that match the label selector.

The figure below shows a Service, called ent, that will load balance to two Pods. It also shows the Endpoints object with the IPs of the two Pods that match the Service’s label selector.

ent will load balance to two Pods
ent will load balance to two Pods

The kubelet process on every node is watching the API server for new Endpoints objects. When it sees them, it creates local networking rules that redirect ClusterIP traffic to Pod IPs. In the modern Linux-based Kubernetes cluster the technology used to create these rules is the Linux IP Virtual Server (IPVS). Older versions of Kubernetes used iptables.

At this point, the Service is fully registered and ready to be discovered:

  • Its front end configuration is registered with DNS.
  • Its back-end configuration is stored in an Endpoints object (or Endpoint slices), and the network is ready to handle traffic.

Let’s summarize the service registration process with the help of a simple flow diagram.

Summarizing Service registration#

You POST a new Service configuration to the API server, and the request is authenticated and authorized. The Service is allocated a ClusterIP, and its configuration is persisted to the cluster store. An associated Endpoint object is created to hold the list of Pod IPs that match the label selector. The cluster DNS is running as a Kubernetes-native application and watching the API server for new Service objects. It sees the new Service and registers the appropriate DNS and SRV records. Every node is running a kube-proxy that sees the new Service and Endpoints objects and creates IPVS rules on every node so that traffic to the Service’s ClusterIP is redirected to one of the Pods that match its label selector.

Introduction

Service Discovery